﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using MultiGed2.Provoz;

namespace MultiGed2.Topologie
{
 /// <summary>
 /// Trida pro definici simulacni oblasti.
 /// </summary>
 public class Oblast
 {
  /// <summary>
  /// Tabulka jizdnich dob v oblasti.
  /// </summary>
  public List<JizdniDoba> jizdniDoby = new List<JizdniDoba>();

  /// <summary>
  /// Seznam dopraven v oblasti.
  /// </summary>
  public List<Dopravna> dopravny = new List<Dopravna>();

  /// <summary>
  /// Seznam tratovych koleji v oblasti.
  /// </summary>
  public List<TrKolej> koleje = new List<TrKolej>();

  /// <summary>
  /// Indikace, zda je v oblasti mozny posun.
  /// </summary>
  public bool posunVOblasti = false;

  /// <summary>
  /// Konstruktor oblasti.
  /// </summary>
  public Oblast()
  {
  }

  /// <summary>
  /// Prida do oblasti kolej.
  /// </summary>
  /// <param name="dopravnaZ">Dopravna, ze ktere kolej vychazi.</param>
  /// <param name="dopravnaDo">Dopravna, kde kolej konci.</param>
  /// <param name="smerZ">Smer koleje z pocatecni dopravny.</param>
  /// <param name="smerDo">Smer koleje do koncove dopravny.</param>
  /// <param name="zpet">Pridat kolej i v opacnem smeru</param>
  private void pridatKolej(Dopravna dopravnaZ, Dopravna dopravnaDo,
   SmerJizdy smerZ, SmerJizdy smerDo, bool zpet)
  {
   koleje.Add(new TrKolej(dopravnaZ, dopravnaDo, smerZ, smerDo));
   if (zpet)
   {
    // opacne smery pro opacnou kolej
    SmerJizdy smerZ2 = (smerDo == SmerJizdy.Lichy ? SmerJizdy.Sudy : SmerJizdy.Lichy);
    SmerJizdy smerDo2 = (smerZ == SmerJizdy.Lichy ? SmerJizdy.Sudy : SmerJizdy.Lichy);
    koleje.Add(new TrKolej(dopravnaDo, dopravnaZ, smerZ2, smerDo2));
   }
  }

  /// <summary>
  /// Prida do oblasti kolej.
  /// </summary>
  /// <param name="dopravnaZ">Dopravna, ze ktere kolej vychazi.</param>
  /// <param name="dopravnaDo">Dopravna, kde kolej konci.</param>
  /// <param name="smerZ">Smer koleje z pocatecni dopravny.</param>
  /// <param name="smerDo">Smer koleje do koncove dopravny.</param>
  /// <param name="zpet">Pridat kolej i v opacnem smeru</param>
  public void pridatKolej(Dopravna dopravnaZ, Dopravna dopravnaDo,
   SmerJizdy smerZ, SmerJizdy smerDo)
  {
   pridatKolej(dopravnaZ, dopravnaDo, smerZ, smerDo, true);
  }

  /// <summary>
  /// Prida do oblasti kolej jen v danem smeru.
  /// </summary>
  /// <param name="dopravnaZ">Dopravna, ze ktere kolej vychazi.</param>
  /// <param name="dopravnaDo">Dopravna, kde kolej konci.</param>
  /// <param name="smerZ">Smer koleje z pocatecni dopravny.</param>
  /// <param name="smerDo">Smer koleje do koncove dopravny.</param>
  public void pridatKolej1(Dopravna dopravnaZ, Dopravna dopravnaDo,
   SmerJizdy smerZ, SmerJizdy smerDo)
  {
   pridatKolej(dopravnaZ, dopravnaDo, smerZ, smerDo, false);
  }

  /// <summary>
  /// Prida do oblasti jizdni doby (JD) mezi dvemi stanicemi.
  /// Pouziva se kvuli jednodussimu volani podle tabulky
  /// v dokumentaci Popis_dat_GVD.
  /// </summary>
  /// <param name="dopravnaZ">Vychozi dopravna.</param>
  /// <param name="dopravnaDo">Cilova dopravna.</param>
  /// <param name="druhVlaku">Druh vlaku.</param>
  /// <param name="t160">JD v minutach pro 160 km/h.</param>
  /// <param name="t150">JD v minutach pro 150 km/h.</param>
  /// <param name="t140">JD v minutach pro 140 km/h.</param>
  /// <param name="t130">JD v minutach pro 130 km/h.</param>
  /// <param name="t120">JD v minutach pro 120 km/h.</param>
  /// <param name="t110">JD v minutach pro 110 km/h.</param>
  /// <param name="t100">JD v minutach pro 100 km/h.</param>
  /// <param name="t90">JD v minutach pro 90 km/h.</param>
  /// <param name="t80">JD v minutach pro 80 km/h.</param>
  /// <param name="t70">JD v minutach pro 70 km/h.</param>
  /// <param name="t60">JD v minutach pro 60 km/h.</param>
  /// <param name="t50">JD v minutach pro 50 km/h.</param>
  /// <param name="t40">JD v minutach pro 40 km/h.</param>
  /// <param name="t30">JD v minutach pro 30 km/h.</param>
  public void pridatJizdniDoby(Dopravna dopravnaZ, Dopravna dopravnaDo, VlDruhJD druhVlaku,
   byte t160, byte t150, byte t140, byte t130, byte t120, byte t110, byte t100,
   byte t90, byte t80, byte t70, byte t60, byte t50, byte t40, byte t30)
  {
   byte[] casy = new byte[14];
   casy[0] = t160;
   casy[1] = t150;
   casy[2] = t140;
   casy[3] = t130;
   casy[4] = t120;
   casy[5] = t110;
   casy[6] = t100;
   casy[7] = t90;
   casy[8] = t80;
   casy[9] = t70;
   casy[10] = t60;
   casy[11] = t50;
   casy[12] = t40;
   casy[13] = t30;
   jizdniDoby.Add(new JizdniDoba(dopravnaZ, dopravnaDo, casy, druhVlaku));
  }

  public byte najdiJizdniDobu(Dopravna dopravnaZ, Dopravna dopravnaDo,
   VlDruhJD druhVlaku, Rychlost rychlost)
  {
   var iterJd = jizdniDoby.Where(
    jd => jd.dopravnaZ == dopravnaZ &&
     jd.dopravnaDo == dopravnaDo &&
     jd.typVlaku == druhVlaku);
   if (iterJd.Count() == 0)
    return 0;
   else
   {
    JizdniDoba jizdniDoba = iterJd.First();
    return jizdniDoba.najdiDobu(rychlost);
   }
  }
 }
}
